// 防抖方法
import debounce from './function/debounce.js'
// 节流方法
import throttle from './function/throttle.js'
// 规则检验
import test from './function/test.js'
export default {
  throttle, // 节流方法
  debounce, // 防抖方法
  test, // 规则检验
  /**
 * @description 格式化时间
 * @param {String|Number} dateTime 需要格式化的时间戳
 * @param {String} fmt 格式化规则 yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 默认yyyy-mm-dd
 * @returns {string} 返回格式化后的字符串
 */
  timeFormat (dateTime = null, formatStr = 'yyyy-mm-dd') {
    let date
    // 若传入时间为假值，则取当前时间
    if (!dateTime) {
      date = new Date()
    }
    // 若为unix秒时间戳，则转为毫秒时间戳（逻辑有点奇怪，但不敢改，以保证历史兼容）
    else if (/^\d{10}$/.test(dateTime?.toString().trim())) {
      date = new Date(dateTime * 1000)
    }
    // 若用户传入字符串格式时间戳，new Date无法解析，需做兼容
    else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) {
      date = new Date(Number(dateTime))
    }
    // 处理平台性差异，在Safari/Webkit中，new Date仅支持/作为分割符的字符串时间
    // 处理 '2022-07-10 01:02:03'，跳过 '2022-07-10T01:02:03'
    else if (typeof dateTime === 'string' && dateTime.includes('-') && !dateTime.includes('T')) {
      date = new Date(dateTime.replace(/-/g, '/'))
    }
    // 其他都认为符合 RFC 2822 规范
    else {
      date = new Date(dateTime)
    }

    const timeSource = {
      'y': date.getFullYear().toString(), // 年
      'm': (date.getMonth() + 1).toString().padStart(2, '0'), // 月
      'd': date.getDate().toString().padStart(2, '0'), // 日
      'h': date.getHours().toString().padStart(2, '0'), // 时
      'M': date.getMinutes().toString().padStart(2, '0'), // 分
      's': date.getSeconds().toString().padStart(2, '0') // 秒
      // 有其他格式化字符需求可以继续添加，必须转化成字符串
    }

    for (const key in timeSource) {
      const [ret] = new RegExp(`${key}+`).exec(formatStr) || []
      if (ret) {
        // 年可能只需展示两位
        const beginIndex = key === 'y' && ret.length === 2 ? 2 : 0
        formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex))
      }
    }

    return formatStr
  },
  /**
 * @description 去除空格
 * @param String str 需要去除空格的字符串
 * @param String pos both(左右)|left|right|all 默认both
 */
  trim (str, pos = 'both') {
    str = String(str)
    if (pos == 'both') {
      return str.replace(/^\s+|\s+$/g, '')
    }
    if (pos == 'left') {
      return str.replace(/^\s*/, '')
    }
    if (pos == 'right') {
      return str.replace(/(\s*$)/g, '')
    }
    if (pos == 'all') {
      return str.replace(/\s+/g, '')
    }
    return str
  },
  /**
   * @description 对象转url参数
   * @param {object} data,对象
   * @param {Boolean} isPrefix,是否自动加上"?"
   * @param {string} arrayFormat 规则 indices|brackets|repeat|comma
  */
  queryParams (data = {}, isPrefix = true, arrayFormat = 'brackets') {
    const prefix = isPrefix ? '?' : ''
    const _result = []
    if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets'
    for (const key in data) {
      const value = data[key]
      // 去掉为空的参数
      if (['', undefined, null].indexOf(value) >= 0) {
        continue
      }
      // 如果值为数组，另行处理
      if (value.constructor === Array) {
        // e.g. {ids: [1, 2, 3]}
        switch (arrayFormat) {
          case 'indices':
            // 结果: ids[0]=1&ids[1]=2&ids[2]=3
            for (let i = 0; i < value.length; i++) {
              _result.push(`${key}[${i}]=${value[i]}`)
            }
            break
          case 'brackets':
            // 结果: ids[]=1&ids[]=2&ids[]=3
            value.forEach((_value) => {
              _result.push(`${key}[]=${_value}`)
            })
            break
          case 'repeat':
            // 结果: ids=1&ids=2&ids=3
            value.forEach((_value) => {
              _result.push(`${key}=${_value}`)
            })
            break
          case 'comma':
            // 结果: ids=1,2,3
            let commaStr = ''
            value.forEach((_value) => {
              commaStr += (commaStr ? ',' : '') + _value
            })
            _result.push(`${key}=${commaStr}`)
            break
          default:
            value.forEach((_value) => {
              _result.push(`${key}[]=${_value}`)
            })
        }
      } else {
        _result.push(`${key}=${value}`)
      }
    }
    return _result.length ? prefix + _result.join('&') : ''
  },
  /**
 * @description 取一个区间数
 * @param {Number} min 最小值
 * @param {Number} max 最大值
 */
  random (min, max) {
    if (min >= 0 && max > 0 && max >= min) {
      const gab = max - min + 1
      return Math.floor(Math.random() * gab + min)
    }
    return 0
  },
  /**
 * @param {Number} len uuid的长度
 * @param {Boolean} firstU 将返回的首字母置为"u"
 * @param {Nubmer} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制
 */
  guid (len = 32, firstU = true, radix = null) {
    const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
    const uuid = []
    radix = radix || chars.length

    if (len) {
      // 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位
      for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]
    } else {
      let r
      // rfc4122标准要求返回的uuid中,某些位为固定的字符
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
      uuid[14] = '4'

      for (let i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | Math.random() * 16
          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]
        }
      }
    }
    // 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class
    if (firstU) {
      uuid.shift()
      return `u${uuid.join('')}`
    }
    return uuid.join('')
  }
}
